package com.hhit.zhgd.service.impl

import cn.afterturn.easypoi.excel.ExcelExportUtil
import cn.afterturn.easypoi.excel.ExcelImportUtil
import cn.afterturn.easypoi.excel.entity.ExportParams
import cn.afterturn.easypoi.excel.entity.ImportParams
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType
import cn.afterturn.easypoi.excel.entity.params.ExcelExportEntity
import cn.afterturn.easypoi.excel.entity.result.ExcelImportResult
import cn.hutool.core.bean.BeanUtil
import cn.hutool.core.collection.CollUtil
import cn.hutool.core.util.StrUtil
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper
import com.baomidou.mybatisplus.core.metadata.IPage
import com.baomidou.mybatisplus.extension.plugins.pagination.Page
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl
import com.hhit.zhgd.dao.ZhgdMaterialsSupplyPlanMapper
import com.hhit.zhgd.domain.dto.BackStageMaterialsSupplyPlanDTO
import com.hhit.zhgd.domain.entity.ZhgdMaterialsSupplyPlan
import com.hhit.zhgd.domain.excelimport.MaterialsSupplyPlanImportParam
import com.hhit.zhgd.domain.response.BaseResp
import com.hhit.zhgd.service.ZhgdMaterialsSupplyPlanService
import com.hhit.zhgd.utils.CustomExcelExportStyler
import jakarta.servlet.http.HttpServletResponse
import org.springframework.beans.BeanUtils
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional
import org.springframework.util.ObjectUtils
import org.springframework.web.multipart.MultipartFile
import java.net.URLEncoder
import java.util.HashMap
import java.util.stream.Collectors

@Service("zhgdMaterialsSupplyPlanService")
class ZhgdMaterialsSupplyPlanServiceImpl : ZhgdMaterialsSupplyPlanService,
    ServiceImpl<ZhgdMaterialsSupplyPlanMapper, ZhgdMaterialsSupplyPlan>() {
    override fun importMaterialsSupplyPlan(multipartFile: MultipartFile?): BaseResp<Any?>? {
        this.remove(QueryWrapper())
        val params = ImportParams()
        // 表头设置为1行
        params.headRows = 1
        val result: ExcelImportResult<MaterialsSupplyPlanImportParam?> =
            ExcelImportUtil.importExcelMore<MaterialsSupplyPlanImportParam>(
                multipartFile!!.inputStream,
                MaterialsSupplyPlanImportParam::class.java, params
            )
        if (CollUtil.isNotEmpty(result.failList)) {
            for (materialsSupplyPlanImportParam in result.failList) {
                val msg =
                    "第" + ((materialsSupplyPlanImportParam?.getRowNum()
                        ?: 0) + 1) + "行的错误是：" + materialsSupplyPlanImportParam?.getErrorMsg()
                return BaseResp.fail("导入失败:$msg")
            }
        }
        val zhgdMaterialsSupplyPlans: MutableList<ZhgdMaterialsSupplyPlan> = CollUtil.newArrayList()
        val materialsSupplyPlanImportParams: List<MaterialsSupplyPlanImportParam?> = result.list
        val filterMaterialsSupplyPlanImportParams: ArrayList<MaterialsSupplyPlanImportParam?> =
            materialsSupplyPlanImportParams.filter {
                StrUtil.isNotBlank(
                    it?.description
                )
            }.toCollection(ArrayList())
        for (materialsSupplyPlanImportParam in filterMaterialsSupplyPlanImportParams) {
            val zhgdMaterialsSupplyPlan = ZhgdMaterialsSupplyPlan()
            BeanUtil.copyProperties(materialsSupplyPlanImportParam, zhgdMaterialsSupplyPlan)
            zhgdMaterialsSupplyPlan.scheduledDeliveryDate = materialsSupplyPlanImportParam?.scheduledDeliveryDate
            zhgdMaterialsSupplyPlan.determineDeliveryDate = materialsSupplyPlanImportParam?.determineDeliveryDate
            zhgdMaterialsSupplyPlan.isCheck = 0
            if (!ObjectUtils.isEmpty(materialsSupplyPlanImportParam?.check) && "已抽检" == materialsSupplyPlanImportParam?.check) {
                zhgdMaterialsSupplyPlan.isCheck = 1
            }
            zhgdMaterialsSupplyPlans.add(zhgdMaterialsSupplyPlan)
        }
        val saveBatchRes = this.saveBatch(zhgdMaterialsSupplyPlans)
        return if (saveBatchRes) {
            BaseResp.success()
        } else {
            BaseResp.fail("导入图纸供应计划数据失败!")
        }
    }

    @Transactional(rollbackFor = [Exception::class])
    override fun confirmHandOverMaterials(id: Int?): BaseResp<Any?>? {
        val zhgdMaterialsSupplyPlan = getById(id)
        zhgdMaterialsSupplyPlan.handOverMaterialsFlag = 1
        val updateRes = updateById(zhgdMaterialsSupplyPlan)
        return if (updateRes) {
            BaseResp.success()
        } else {
            BaseResp.fail("修改交货状态失败")
        }
    }

    @Transactional(rollbackFor = [Exception::class])
    override fun addMaterialPlan(backStageMaterialsSupplyPlanDTO: BackStageMaterialsSupplyPlanDTO?): BaseResp<Any?>? {
        val zhgdMaterialsSupplyPlan = ZhgdMaterialsSupplyPlan()
        BeanUtils.copyProperties(backStageMaterialsSupplyPlanDTO!!, zhgdMaterialsSupplyPlan)
        val addRes = save(zhgdMaterialsSupplyPlan)
        return if (addRes) {
            BaseResp.success()
        } else BaseResp.fail("添加物资供应计划失败!")
    }

    @Transactional(rollbackFor = [Exception::class])
    override fun editMaterialPlan(backStageMaterialsSupplyPlanDTO: BackStageMaterialsSupplyPlanDTO?): BaseResp<Any?>? {
        val zhgdMaterialsSupplyPlan = ZhgdMaterialsSupplyPlan()
        BeanUtils.copyProperties(backStageMaterialsSupplyPlanDTO!!, zhgdMaterialsSupplyPlan)
        val editRes = updateById(zhgdMaterialsSupplyPlan)
        return if (editRes) {
            BaseResp.success()
        } else BaseResp.fail("修改物资供应计划失败!")
    }

    @Transactional(rollbackFor = [Exception::class])
    override fun delMaterialPlan(ids: List<Int?>?): BaseResp<Any?>? {
        return if (CollUtil.isNotEmpty(ids)) {
            val delRes = this.removeByIds(ids)
            if (delRes) {
                BaseResp.success()
            } else {
                BaseResp.fail("删除物资供应计划失败!")
            }
        } else {
            BaseResp.fail("无可删除的数据!")
        }
    }

    override fun getMaterialPlanPageInfo(
        keyWord: String?,
        page: Int,
        size: Int
    ): IPage<BackStageMaterialsSupplyPlanDTO>? {
        val queryWrapper = QueryWrapper<ZhgdMaterialsSupplyPlan>()
        if (StrUtil.isNotBlank(keyWord)) {
            queryWrapper.like("description", keyWord)
                .or().like("purchase_number", keyWord)
                .or().like("measuring_unit", keyWord)
                .or().like("supplier_name", keyWord)
                .or().like("supplier_contact", keyWord)
                .or().like("supplier_contact_phone", keyWord)
                .or().like("scheduled_delivery_date", keyWord)
                .or().like("determine_delivery_date", keyWord)
        }
        val pageRequest = Page<ZhgdMaterialsSupplyPlan>(page.toLong(), size.toLong())
        val zhgdMaterialsSupplyPlanPage: IPage<ZhgdMaterialsSupplyPlan> = this.page(pageRequest, queryWrapper)
        // Convert to DTO
        val dtoList = zhgdMaterialsSupplyPlanPage.records.map { entity: ZhgdMaterialsSupplyPlan? ->
            val dto = BackStageMaterialsSupplyPlanDTO()
            BeanUtils.copyProperties(entity!!, dto)
            dto
        }.toCollection(ArrayList())
        val dtoPage: IPage<BackStageMaterialsSupplyPlanDTO> =
            Page(page.toLong(), size.toLong(), zhgdMaterialsSupplyPlanPage.total)
        dtoPage.records = dtoList
        return dtoPage
    }

    override fun exportMaterialPlan(response: HttpServletResponse?) {
        val materialsSupplyPlans = this.list()
        val list: MutableList<BackStageMaterialsSupplyPlanDTO> = java.util.ArrayList()
        for (zhgdMaterialsSupplyPlan in materialsSupplyPlans) {
            val backStageMaterialsSupplyPlanDTO = BackStageMaterialsSupplyPlanDTO()
            BeanUtils.copyProperties(zhgdMaterialsSupplyPlan!!, backStageMaterialsSupplyPlanDTO)
            list.add(backStageMaterialsSupplyPlanDTO)
        }
        // 设计表头格式
        val materialsSupplyPlanTableHeaderList: List<ExcelExportEntity> = getExportRebateOffsetTableHeader()
        // 根据表头对应的key填充数据
        val materialsSupplyPlanRecordList: List<Map<String, Any>?> = getExportRebateOffsetCallRecord(list)

        val exportParams = ExportParams(null, "")
        exportParams.type = ExcelType.HSSF
        exportParams.style = CustomExcelExportStyler::class.java
        // 根据表头和数据导出Excel
        val workbook =
            ExcelExportUtil.exportExcel(exportParams, materialsSupplyPlanTableHeaderList, materialsSupplyPlanRecordList)

        response!!.characterEncoding = "UTF-8"
        response!!.contentType = "application/vnd.ms-excel"
        response!!.setHeader(
            "Content-disposition",
            "attachment;filename=" + URLEncoder.encode(
                String.format("%s_%s.xls", "物资供应计划", System.currentTimeMillis()),
                "UTF-8"
            )
        )
        workbook.write(response!!.outputStream)
        workbook.close()
    }


    private fun getExportRebateOffsetTableHeader(): List<ExcelExportEntity> {
        // 表头设置
        val materialsSupplyPlanTableHeaderList: MutableList<ExcelExportEntity> = java.util.ArrayList()
        val sortEntity = ExcelExportEntity("序号", "sort")
        //        planStartEntity.setMergeVertical(true);
        materialsSupplyPlanTableHeaderList.add(sortEntity)
        val descriptionEntity = ExcelExportEntity("物料描述", "description")
        //        planCompleteEntity.setMergeVertical(true);
        materialsSupplyPlanTableHeaderList.add(descriptionEntity)
        val purchaseNumberEntity = ExcelExportEntity("采购申请数量", "purchaseNumber")
        //        plannedTimeEntity.setMergeVertical(true);
        materialsSupplyPlanTableHeaderList.add(purchaseNumberEntity)
        val measuringUnitEntity = ExcelExportEntity("度量单位", "measuringUnit")
        //        actualStartEntity.setMergeVertical(true);
        materialsSupplyPlanTableHeaderList.add(measuringUnitEntity)
        val supplierNameEntity = ExcelExportEntity("供应商名称", "supplierName")
        //        actualStartEntity.setMergeVertical(true);
        materialsSupplyPlanTableHeaderList.add(supplierNameEntity)
        val supplierContactEntity = ExcelExportEntity("供应商联系人", "supplierContact")
        //        actualStartEntity.setMergeVertical(true);
        materialsSupplyPlanTableHeaderList.add(supplierContactEntity)
        val supplierContactPhoneEntity = ExcelExportEntity("供应商联系人电话", "supplierContactPhone")
        //        actualStartEntity.setMergeVertical(true);
        materialsSupplyPlanTableHeaderList.add(supplierContactPhoneEntity)
        val scheduledDeliveryDateEntity = ExcelExportEntity("合同计划交货日期", "scheduledDeliveryDate")
        //        actualStartEntity.setMergeVertical(true);
        materialsSupplyPlanTableHeaderList.add(scheduledDeliveryDateEntity)
        val determineDeliveryDateEntity = ExcelExportEntity("确定交货期", "determineDeliveryDate")
        //        actualStartEntity.setMergeVertical(true);
        materialsSupplyPlanTableHeaderList.add(determineDeliveryDateEntity)
        //        statusEntity.setMergeVertical(true);
        return materialsSupplyPlanTableHeaderList
    }

    private fun getExportRebateOffsetCallRecord(list: List<BackStageMaterialsSupplyPlanDTO>): List<Map<String, Any>> {
        val materialsSupplyPlanRecordList: MutableList<Map<String, Any>> = java.util.ArrayList()
        for (i in list.indices) {
            val materialsSupplyPlanRecordMap: MutableMap<String, Any> = HashMap()
            materialsSupplyPlanRecordMap["sort"] = i + 1
            materialsSupplyPlanRecordMap["description"] = list[i].description?:""
            materialsSupplyPlanRecordMap["purchaseNumber"] = list[i].purchaseNumber?:""
            materialsSupplyPlanRecordMap["measuringUnit"] = list[i].measuringUnit?:""
            materialsSupplyPlanRecordMap["supplierName"] = list[i].supplierName?:""
            materialsSupplyPlanRecordMap["supplierContact"] = list[i].supplierContact?:""
            materialsSupplyPlanRecordMap["supplierContactPhone"] = list[i].supplierContactPhone?:""
            materialsSupplyPlanRecordMap["scheduledDeliveryDate"] = list[i].scheduledDeliveryDate?:""
            materialsSupplyPlanRecordMap["determineDeliveryDate"] = list[i].determineDeliveryDate?:""
            materialsSupplyPlanRecordList.add(materialsSupplyPlanRecordMap)
        }
        return materialsSupplyPlanRecordList
    }
}